﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace _3D
{
    public partial class FormAbout : Form
    {
        private const int PSize = 128;

		private int    cx, cy;
		private double angle = 0.0, angle2 = 0.0;

		private Timer  locTimer;
		private bool   painting = false;
		private Bitmap picFracSource;

		public FormAbout()
		{
			this.SetStyle(ControlStyles.DoubleBuffer, true);
			this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);

			picFracSource = new Bitmap( PSize, PSize, PixelFormat.Format24bppRgb );

			locTimer = new Timer();
			locTimer.Interval = 15;
			locTimer.Tick += new System.EventHandler(locTimer_Tick);
            
            InitializeComponent();

			locTimer.Enabled = true;
		}

		private void locTimer_Tick(object sender, EventArgs e)
		{
			angle += 0.023; angle2+= 0.027;
			cx = (int)( 800.0 * Math.Sin( angle+1.0 ) ); 
			cy = (int)( 800.0 * Math.Cos( angle2 ) );

			if ( painting == false )
			{
				painting = true;
				JuliaPaint();
				painting = false;
			}
		}

		private void JuliaPaint()
		{
			Rectangle bounds = 
				new Rectangle( new Point(0, 0), 
				new Size( picFracSource.Width, picFracSource.Height ) ); 
			BitmapData bData = picFracSource.LockBits( bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb );
           
			byte[] picData = new byte[PSize * PSize * 3];
			int iDex = 0;

			int iterNo, i, j;
			int x, y, xn, yn, x2, y2;
			for (i=0; i<PSize; i++ )
				for (j=0; j<PSize; j++ )
				{
					iterNo = 0;
					x  = (i<<5)-2048; 
					y  = (j<<5)-2048;
					x2 = x*x;  
					y2 = y*y;
					while ( 
						( iterNo++ < 32 ) && 
						( Math.Abs(x2+y2) < 4000000 ) 
						)
					{
						x2 = x*x; y2 = y*y;
						xn = ((x2-y2)>>10) + cx;
						yn = ((x*y)>>9)    + cy;
						x  = xn; y  = yn;
					}

					picData[iDex++] = Convert.ToByte(255-iterNo);
					picData[iDex++] = Convert.ToByte(5*iterNo);
					picData[iDex++] = Convert.ToByte(5*iterNo);
                }

			Marshal.Copy ( picData, 0, bData.Scan0, PSize * PSize * 3 );
           
            picFracSource.UnlockBits( bData );
			this.picFrac.Image = picFracSource; 
			this.picFrac.Invalidate();
        }
    }
}
